﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Runtime.Serialization;

namespace Northwind.NET.Security
{
	public class SecureCollection<T> : IList<T>, INotifyPropertyChanged
	{
		private List<T> items;

		public SecureCollection()
		{
			this.items = new List<T>();
		}

		#region IList<T> Members
		public int IndexOf(T item)
		{
			return items.IndexOf(item);
		}

		public void Insert(int index, T item)
		{
			items.Insert(index, item);
			ItemAdded(item, index);
			OnPropertyChanged("Items");
		}

		public void RemoveAt(int index)
		{
			T item = items[index];
			items.RemoveAt(index);
			ItemRemoved(item);
			OnPropertyChanged("Items");
		}

		public T this[int index]
		{
			get
			{
				return items[index];
			}
			set
			{
				items[index] = value;
				OnPropertyChanged("Items");
			}
		}
		#endregion

		public void Move(int currentIndex, int newIndex)
		{
			T item = items[currentIndex];
			items.RemoveAt(currentIndex);
			items.Insert(newIndex, item);
		}

		#region ICollection<T> Members
		public void Add(T item)
		{
			items.Add(item);
			ItemAdded(item, items.Count - 1);
			OnPropertyChanged("Items");
		}

		public void Clear()
		{
			items.Clear();
			OnPropertyChanged("Items");
		}

		public bool Contains(T item)
		{
			return items.Contains(item);
		}

		public void CopyTo(T[] array, int arrayIndex)
		{
			items.CopyTo(array, arrayIndex);
		}

		public int Count
		{
			get { return items.Count; }
		}

		public bool IsReadOnly
		{
			get { return false; }
		}

		public bool Remove(T item)
		{
			bool result = items.Remove(item);
			if (result)
			{
				ItemRemoved(item);
			}
			OnPropertyChanged("Items");
			return result;
		}
		#endregion

		#region List Modification Notification
		protected virtual void ItemAdded(T item, int addedAt)
		{
		}

		protected virtual void ItemRemoved(T item)
		{
		}
		#endregion
		

		#region IEnumerable<T> Members
		public IEnumerator<T> GetEnumerator()
		{
			return items.GetEnumerator();
		}
		#endregion

		#region IEnumerable Members
		System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
		{
			return items.GetEnumerator();
		}
		#endregion

		public virtual bool HasValue
		{
			get
			{
				return Count > 0;
			}
		}

		public virtual SecurityHandle? SecurityHandle
		{
			get
			{
				if (this.Count == 0)
				{
					return null;
				}
				SecurityHandle result = new SecurityHandle("U");
				return result;
			}
		}

		public virtual void Sort(Comparison<T> comparison)
		{
			items.Sort(comparison);
		}

		#region INotifyPropertyChanged Members

		public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
		/// <summary>
		/// Raises this object's PropertyChanged event.
		/// </summary>
		/// <param name="propertyName">The property that has a new value.</param>
		protected virtual void OnPropertyChanged(string propertyName)
		{


			// Is anybody out there?
			System.ComponentModel.PropertyChangedEventHandler handler = this.PropertyChanged;
			if (handler == null) return;

			// Somebody is listening, so raise a property changed event
			var args = new System.ComponentModel.PropertyChangedEventArgs(propertyName);
			handler(this, args);
		}
		
		#endregion
	}


	public enum PermissionTypeEnum
	{
		R, W, X
	}
	
}

